#define _CRT_SECURE_NO_WARNINGS 1
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//	//没有返回值,函数名与类名相同
//	/*Date()
//	{
//		_year = 1;
//		_month = 1;
//		_day = 1;
//	}*/
//	//构造函数可以重载
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void Print()
//	{
//		cout << _year << "/" << _month << "/" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//int main()
//{
//	//构造函数对象实例化的时候自动调用
//	//调用无参 - 没有参数的时候不能加括号,加括号就报错,
//	//因为存在歧义,Date f1();这是函数的声明还是对象的定义
//	//规定不能这么写
//	//对象加参数
//	Date d1;//不传参
//	Date d2(2024,8,8);//传参
//
//	d1.Print();
//	d2.Print();
//
//	Date d3(2024);//传一部分参数
//	d3.Print();
//
//	return 0;
//}
/*
我们以后对于一个类,要初始化这个对象,那么我们应该去写它的
构造函数,并且定义对象的时候就自动调用,好处就是写了构造,
对象就一定被初始化了,
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
上面这两个函数构成函数重载,函数名相同参数不同,但是它们调用的时候会
存在歧义,所以不能这样写,如果无参的时候调用的话既可以调用第一个,又可
以调用第二个,所以不知道调谁,不会把无参的和全缺省的一起写。

构造一般情况下可以提供多个,但是其中一个提供全缺省的会非常的好,如果调用
不传参,它会全部用缺省的,如果想显示调用,就传参,其次还可以只传一部分参数
*/

//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//	//如果不写编译器默认生成一个构造函数
//	
//	//带参的构造函数 - 不是默认构造(无参的和全缺省的是默认构造)
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	void Print()
//	{
//		cout << _year << "/" << _month << "/" << _day << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//typedef int STDataType;
//class Stack
//{
//public:
//
//	Stack()
//	{
//		_a = nullptr;
//		_capacity = _top = 0;
//	}
//
//	Stack(int n)
//	{
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc error!\n");
//			exit(1);
//		}
//		_capacity = n;
//		_top = 0;
//	}
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//class MyQueue
//{
//private:
//	Stack _pushst;
//	Stack _popst;
//	int _size;
//};
//int main()
//{
//	Date d1;
//	d1.Print();
//	//栈
//	//Stack st1;
//
//	MyQueue mq;
//	return 0;
//}

//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
	//必须是自身类类型的引用
	//Date d2(d1)
	//Date(Date* d)//这里使用指针也是可以的,因为指针也不需要调用拷贝构造
	//{
	//	_year = d->_year;
	//	_month = d->_month;
	//	_day = d->_day;
	//}
	//Date(const Date& d,int x)
	//{
	//	//this->_year = d._year;
	//	_year = d._year;
	//	_month = d._month;
	//	_day = d._day;
	//}
//	~Date()
//	{
//		//日期类没有资源需要清理,所以这里写个打印就可以了
//		cout << "~Date()" << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//typedef int STDataType;
//class Stack
//{
//public:
//	Stack(int n = 4)
//	{
//		_a = (STDataType*)malloc
//		(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//	//Stack st2 == st1
//	Stack(const Stack& st)
//	{
//		//申请空间
//		_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);
//		if (_a == nullptr)
//		{
//			perror("malloc error!\n");
//			exit(1);
//		}
//		memcpy(_a, st._a, sizeof(STDataType) * st._top);
//		_top = st._top;
//		_capacity = st._capacity;
//
//	}
//	void Push(STDataType x)
//	{
//		if (_top == _capacity)
//		{
//			int newcapacity = _capacity * 2;
//			STDataType* tmp = (STDataType*)realloc(_a, newcapacity *
//				sizeof(STDataType));
//			if (tmp == NULL)
//			{
//				perror("realloc fail");
//				return;
//			}
//			_a = tmp;
//			_capacity = newcapacity;
//		}
//		_a[_top++] = x;
//	}
//	STDataType Top()
//	{
//		return _a[_top - 1];
//	}
//	//函数名是在类名前面加~,表示跟构造函数的功能是反的
//	~Stack()
//	{
//		cout << "~Stack()" << endl;
//		//清理空间就是free这块空间
//		free(_a);
//		_a = nullptr;
//		_top = _capacity = 0;
//	}
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//class MyQueue
//{
//public:
//	~MyQueue()
//	{
//		//假设这里是释放堆上的空间
//		cout << "~MyQueue()" << endl;
//	}
//private:
//	Stack _pushst;
//	Stack _popst;
//	//int* ptr; - 指向堆上的指针
//};
////void Func(Date& d)
////{
////
////}
//Date f()
//{
//	Date ret;
//	return ret;
//}
//Stack& Func()
//{
//	static Stack st;
//	st.Push(1);
//	st.Push(2);
//	st.Push(3);
//	st.Push(4);
//	return st;
//}
//
//int main()
//{
//	/*Date d1(2024, 8, 9);
//	Date d2 = d1;*/
//
//	Stack ret = Func();
//	cout << ret.Top() << endl;
//
//	//MyQueue m1;
//	//MyQueue m2(m1);
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	bool operator<(const Date& x)
//	{
//		if (_year < x._year)
//			return true;
//		else if (_year == x._year &&
//			_month < x._month)
//			return true;
//		else if (_year == x._year &&
//			_month == x._month &&
//			_day < x._day)
//			return true;
//		return false;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//int main()
//{
//	Date d1(2024, 8, 11);
//	Date d2(2024, 8, 12);
//
//	//可以显示调用,把运算符重载当成一个普通函数,
//	//但是补一般不会这样写,运算符重载就是为了可读性高
//	//编译器看到这个就是函数调用
//	int ret1 = d1.operator<(d2);
//	//编译器看到这个就会转换成上面的,多了一次识别
//	int ret2 = d1 < d2;
//	cout << ret1 << endl;
//	cout << ret2 << endl;
//	return 0;
//}

//#include <iostream>
//#include <assert.h>
//using namespace std;
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//	bool operator<(Date& x)
//	{
//		if (_year < x._year)
//			return true;
//		if (_year == x._year && _month < x._month)
//			return true;
//		if (_year == x._year && _month == x._month && _day < x._day)
//			return true;
//		return false;
//	}
//	//d1 == d2 --> d1.operator==(d2)
//	bool operator==(Date& x)
//	{
//		return _year == x._year &&
//			_month == x._month &&
//			_day == x._day;
//	}
//	int GetMonthDay(int year, int month)
//	{
//		assert(month >= 1 && month <= 12);
//		//
//		static int arr[] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };
//		if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
//		{
//			return 29;
//		}
//		return arr[month];
//	}
	////重载前置++
	//Date& operator++()
	//{
	//	_day++;
	//	if (_day > GetMonthDay(_year, _month))
	//	{
	//		_month++;
	//		_day = 1;
	//		if (_month > 12)
	//		{
	//			_year++;
	//			_month = 1;
	//		}
	//	}
	//	return *this;
	//}
	//
	////后置++
	//Date operator++(int)
	//{
	//	Date tmp = *this;
	//	++(*this);
	//	return tmp;
	//}
	// +=
//	Date& operator+=(int x)
//	{
//		_day += x;
//		while (_day > GetMonthDay(_year, _month))
//		{
//			_day -= GetMonthDay(_year, _month);
//			_month++;
//			if (_month > 12)
//			{
//				_year++;
//				_month = 1;
//			}
//		}
//		return *this;
//	}
//	//重载前置++
//	Date& operator++()
//	{
//		*this += 1;
//		return *this;
//	}
//	//重载后置++
//	Date operator++(int)
//	{
//		//后置++要返回++之前的值,所以要先把值保存起来再++
//		Date tmp = *this;//拷贝构造
//		*this += 1;
//		return tmp;
//	}
//	void Printf()
//	{
//		cout << _year << "年" << _month << "月" << _day << "日" << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};

//编译报错:"operator+"必须至少有一个类类型的形参
//int operator+(int x, int y)
//{
//	return x - y;
//}

//class A
//{
//public:
//	void func()
//	{
//		cout << "A::func()" << endl;
//	}
//};
//函数指针都是嵌套的
//typedef void(A::* PF)();
//int main()
//{
	//函数指针和数组指针都是嵌套定义
	//void(A:: *pf)();
	/*PF pf = &A::func;
	A obj;*/
	//对象调用成员函数函数指针时,使用.*运算符
	//调用函数,但是这个函数是函数指针,所以对
	//函数指针先解引用
	//(obj.*pf)();

//	Date d1(2024,8,11);
//	Date d2(2024,8,12);
//	//运算符重载可以显示调用
//	d1.operator==(d2);
//	//编译器会转换成d1.operator==(d2);
//	d1 == d2;
//
//	d1.Printf();
//	++d1;
//	d1.Printf();
//	
//
//	return 0;
//}

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//d2 = d3;
	//d2.operator(d3);
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2024, 8, 12);

	//拷贝初始化 - 调用拷贝构造
	Date d2(d1);

	//这个是拷贝构造 -> 一个已经存在的对象初始化给另一个要创建的对象
	Date d4 = d1;

	Date d3(2024, 8, 12);

	//赋值运算符重载 -> 用于完成两个已经存在的对象之间的拷贝赋值
	d1 = d2 = d3;
	//d1.operator=(d3);

	d1 = d1;

	int i, j, k;
	i = j = k = 1;

	return 0;
}

/*
拷贝构造:拿一个已经存在的对象取拷贝另一个现在要创建初始化的对象
赋值运算符重载:两个已经存在的对象,把一个已经存在的对象拷贝给另一个已经
存在的对象
*/